package com.gegong.imr.client.vbox.cmd;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.virtualbox_5_2.IMachine;
import org.virtualbox_5_2.ISession;
import org.virtualbox_5_2.LockType;
import org.virtualbox_5_2.VirtualBoxManager;

import java.util.Optional;


/**
 * 修改虚拟机设置的命令
 */
@Slf4j
public class ModifyVmSettingsCmd extends AbstractVBoxCmd {
    public ModifyVmSettingsCmd(@NonNull VirtualBoxManager virtualBoxManager, @NonNull String targetVm) {
        super(virtualBoxManager, targetVm);
    }


    @Override
    public Progress execute(Object... params) {
        try {
            super.execute(params);
            VmSettings settings = (VmSettings) params[0];
            IMachine machine = getVirtualBox().findMachine(getTargetVm());
            log.info("当前虚拟机会话状态:" + machine.getSessionState().name());
            ISession session = getVirtualBoxManager().getSessionObject();

            try {
                machine.lockMachine(session, LockType.VM);
                log.info("当前虚拟机会话状态:" + machine.getSessionState().name());

                log.info("#########修改虚拟机基本设置");
                Optional.ofNullable(settings.getBasicSetting()).map(VmSettings.BasicSetting::getName).ifPresent(name -> {
                    session.getMachine().setName(name);
                });

                log.info("#########修改虚拟机网络设置");
                Optional.ofNullable(settings.getNetworkAdapterSettings()).filter(CollectionUtils::isNotEmpty).ifPresent(nss -> {
                    nss.forEach(ns -> {
                        Optional.ofNullable(ns).map(VmSettings.NetworkAdapterSetting::getMacAddress).ifPresent(mac -> {
                            log.info("设置新网卡地址:" + ns.getMacAddress());
                            session.getMachine().getNetworkAdapter(ns.getSlot()).setMACAddress(ns.getMacAddress());

                        });
                    });
                });

                log.info("保存虚拟机设置...");
                session.getMachine().saveSettings();
            } finally {
                session.unlockMachine();
            }
        } catch (Exception e) {
            progress.resultCode = Progress.RESULT_FAILURED;
            progress.errorInfo = e;
        } finally {
            progress.completed = true;
        }

        return progress;
    }

    @Override
    public String getName() {
        return String.format("修改虚拟机{%s}设置", getTargetVm());
    }
}
